#ifndef SOCKETGLOBAL_H
#define SOCKETGLOBAL_H

#include "../_Global/GlobalClass.h"

//////////////通信信息////////////

//s给c发送的数据
//#define GAME_CLIENT 200





//client与InfoServer交互
#define INFO_SERVER_REQUEST              1000
#define INFO_SERVER_RESPONSE             1100

//登录信息
#define INFO_SERVER_LOGIN                   10      //后跟用户名和密码
#define INFO_SERVER_LOGIN_SUCCESS               0   //登录成功,后跟32位id
#define INFO_SERVER_LOGIN_FAIL                  1   //登录失败,后跟错误代码:-1登录错误,-2重复登陆

//注册,后跟用户名，昵称和密码
#define INFO_SERVER_REGISTER                20
#define INFO_SERVER_REGISTER_SUCCESS            0   //注册成功
#define INFO_SERVER_REGISTER_FAIL               1   //注册失败

//服务器信息
#define INFO_SERVER_SERVERINFO              30      //服务器信息
#define INFO_SERVER_SERVERINFO_SUCCESS          0   //登录成功,后跟32位id
#define INFO_SERVER_SERVERINFO_FAIL             1   //登录失败,后跟错误代码:-1登录错误,-2重复登陆




//client与GameInfoServer交互
#define GAME_SERVER_REQUEST             2000
#define GAME_SERVER_RESPONSE            2100


//获取,后跟用户名，昵称和密码
#define GAME_SERVER_GAMEUSERINFO            10      //用户信息
#define GAME_SERVER_GAMEUSERINFO_SUCCESS        0   //成功
#define GAME_SERVER_GAMEUSERINFO_FAIL           1   //失败

//注册,后跟用户名，昵称和密码
#define GAME_SERVER_REGISTERGAMEUSERINFO    20          //用户信息
#define GAME_SERVER_REGISTERGAMEUSERINFO_SUCCESS    0   //成功
#define GAME_SERVER_REGISTERGAMEUSERINFO_FAIL       1   //失败

//课程信息
#define GAME_SERVER_CLASSINFO               40          //课程信息
#define GAME_SERVER_CLASSINFO_SUCCESS            0      //成功
#define GAME_SERVER_CLASSINFO_FAIL               1      //失败

#define GAME_SERVER_STUDYINFO               50          //学习信息
#define GAME_SERVER_STUDYINFO_SUCCESS            0      //成功
#define GAME_SERVER_STUDYINFO_FAIL               1      //失败

#define GAME_SERVER_SAVESTUDYINFO           60          //保存学习信息
#define GAME_SERVER_SAVESTUDYINFO_SUCCESS        0      //成功
#define GAME_SERVER_SAVESTUDYINFO_FAIL           1      //失败

#define GAME_SERVER_UPDATESCORE             70          //保存学习信息
#define GAME_SERVER_UPDATESCORE_SUCCESS          0      //成功
#define GAME_SERVER_UPDATESCORE_FAIL             1      //失败

#define GAME_SERVER_RANKING                 80          //课程信息
#define GAME_SERVER_RANKING_SUCCESS             0       //成功
#define GAME_SERVER_RANKING_FAIL                1       //失败

#define GAME_SERVER_ITEMS                   85          //课程信息
#define GAME_SERVER_ITEMS_SUCCESS               0       //成功
#define GAME_SERVER_ITEMS_FAIL                  1       //失败


//房间
#define GAME_SERVER_GROUP_CREATE                200     //创建房间
#define GAME_SERVER_GROUP_CREATE_SUCCESS        0
#define GAME_SERVER_GROUP_CREATE_FAIL           1

#define GAME_SERVER_GROUP_CLOSE                 205     //[服务端发送给所有客户]后跟GroupID
//#define GAME_SERVER_GROUP_CLOSE_SUCCESS         0     //注册成功
//#define GAME_SERVER_GROUP_CLOSE_FAIL            1     //注册失败
#define GAME_SERVER_GROUP_UPDATE                210     //[服务器发送]更新房间信息

//加入游戏
#define GAME_SERVER_GROUP_JOINGROUP             215     //后跟GroupID
#define GAME_SERVER_GROUP_JOINGROUP_SUCCESS     0       //后跟GroupID
#define GAME_SERVER_GROUP_JOINGROUP_FAIL        1       //后跟Err:-1没有找到房间;-2所有房间满;-3房间正在玩;-4已经加入了该房间
//#define GAME_SERVER_GROUP_JOIN_NOROOM           1
//#define GAME_SERVER_GROUP_JOIN_ROOMFULL         2
//#define GAME_SERVER_GROUP_JOIN_HAVEJOINED       3
//#define GAME_SERVER_GROUP_JOIN_NOTWAITING       4
//#define GAME_SERVER_GROUP_JOIN_PASSERR          5

#define GAME_SERVER_GROUP_MESSAGE               220     //

//别人的信息
#define GAME_SERVER_GROUP_OTHERSINFO            225
#define GAME_SERVER_GROUP_OTHERSINFO_JOINGROUP  1       //true,false
#define GAME_SERVER_GROUP_OTHERSINFO_READY      2       //
#define GAME_SERVER_GROUP_OTHERSINFO_MESSAGE    3       //

//退房间
#define GAME_SERVER_GROUP_EXITGROUP             230
#define GAME_SERVER_GROUP_EXITGROUP_SUCCESS     0
#define GAME_SERVER_GROUP_EXITGROUP_FAIL        1

//客户端给server 准备开始游戏 或 不准备开始游戏(1个参数)
#define GAME_SERVER_GROUP_GETREADY              235     //[客户端发送]后跟 是否准备好
#define GAME_SERVER_GROUP_GETREADY_SUCCESS      0       //[客户端发送]后跟 是否准备好
#define GAME_SERVER_GROUP_GETREADY_FAIL         1       //[客户端发送]后跟 是否准备好


//发送所有房间信息
//#define GAME_SERVER_GROUP_SENDCREATEINFOS       205
#define GAME_SERVER_GROUP_SENDALLGROUPINFOS     240     //后跟每一个group的序号,id,人数,最大玩家数,-1为结束
//#define GAME_SERVER_GROUP_SENDALLGROUPINFOS     205



//c给s,请求游戏开始(单人不回复,只是改变状态)
#define GAME_SERVER_STARTGAME                   300
#define GAME_SERVER_STARTGAME_SUCCESS           0
#define GAME_SERVER_STARTGAME_FAIL              1

//c给s,初始化完毕
#define GAME_SERVER_INITOVER                    305

//客户端给server,单人游戏结束,改变状态
#define GAME_SERVER_GAMEOVER                    310
//#define GAME_SERVER_GAMEOVER_SUCCESS            0
//#define GAME_SERVER_GAMEOVER_FAIL               1





//s给c们转发的数据
#define GAME_DATA                       3000
//游戏开始.后跟是否为host,玩家ID,玩家数,玩家信息
//#define GAME_DATA_GAMESTART                     101         //后跟玩家座位号,最大玩家数,是否房主,各玩家类型
//游戏结束
//#define GAME_DATA_GAMEOVER                      102         //后跟结束类型

//洗牌数据，后跟 PaiDuiShu和m_PaiDuiID大小，m_PaiDuiID
#define GAME_DATA_TRANSFER_CHOICEWUJIANG    10          //客户给服务器 选择武将
#define GAME_DATA_TRANSFER_ALLWUJIANGCHOICED    15      //服务器给客户转发 所有选择的武将
#define GAME_DATA_TRANSFER_RANDOM           20          //晒点数据,后跟qint16
#define GAME_DATA_TRANSFER_XIPAI            30          //洗牌
#define GAME_DATA_TRANSFER_CHUPAI           40          //出牌数据,后面跟 ret 和 step大小，step
#define GAME_DATA_TRANSFER_WENTI            50          //转发英语,后跟所有英语数据
#define GAME_DATA_TRANSFER_ANSWER           60          //转发英语,后跟答案



#define GAME_DATA_MAX_LENGTH 4096

//需要发送的游戏数据
struct _GameData: public __ProducerData
{
    explicit _GameData()
    {
        //memset(this, 0, sizeof(_GameData));
    }
    virtual ~_GameData() Q_DECL_OVERRIDE
    {
    }

    virtual void Release() Q_DECL_OVERRIDE    //数据需要释放
    {
        switch(type)
        {
        case GAME_DATA_TRANSFER_XIPAI:
            {
                if(XiPaiData.pData != nullptr)
                    delete XiPaiData.pData;
                XiPaiData.pData = nullptr;
            }
            break;
        case GAME_DATA_TRANSFER_CHUPAI:
            {
                if(ChuPaiData.pData != nullptr)
                    delete ChuPaiData.pData;
                ChuPaiData.pData = nullptr;
            }
            break;
        case GAME_DATA_TRANSFER_ALLWUJIANGCHOICED:
            {
                //if(ChoiceWuJiangData.pWuJiangData != nullptr)
                //    delete ChoiceWuJiangData.pWuJiangData;
                //ChoiceWuJiangData.pWuJiangData = nullptr;
            }
            break;
        case GAME_DATA_TRANSFER_WENTI:
        case GAME_DATA_TRANSFER_ANSWER:
        case GAME_DATA_TRANSFER_RANDOM:
        case GAME_DATA_TRANSFER_CHOICEWUJIANG:
            {
            }
            break;
        default:
            break;
        }

    }

    //数据具体类型定义
    union
    {
        //GAME_DATA_TRANSFER_ALLWUJIANGCHOICED:
        struct
        {
            qint16 nPlayerCount;    //玩家数
            qint16 nWuJiangCount;   //一个玩家的武将数
            //qint16 *pWuJiangData;    //武将数据
        }ChoiceWuJiangData;


        //GAME_DATA_TRANSFER_XIPAI:
        struct
        {
            qint16  nData;       //存放PaiDuiShu
            qint16  nDataLength;  //data长度
            char    *pData;         //存放PaiDuiID的具体值
        }XiPaiData;


        //GAME_DATA_TRANSFER_CHUPAI:
        struct
        {
            qint16  nData;       //存放 ret值(按钮)
            qint16  nDataLength;  //data长度
            char    *pData;         //step
        }ChuPaiData;


        //GAME_DATA_TRANSFER_WENTI
        //_EnglishWord *WenTiData;
        struct
        {
            qint32 arrayID[4];
            qint16 nAnswer;
        }WenTiData;


        //GAME_DATA_TRANSFER_ANSWER:
        qint16 nAnswer;


        //GAME_DATA_TRANSFER_RANDOM
        qint32 nRandom;

    };


    //检查从网络收到的游戏数据是否合法
    bool CheckGameData()
    {
        if(this == nullptr)
            return false;

        switch(this->type)
        {
        case GAME_DATA_TRANSFER_CHOICEWUJIANG:
        case GAME_DATA_TRANSFER_ALLWUJIANGCHOICED:
            break;
        case GAME_DATA_TRANSFER_XIPAI:
            if(this->XiPaiData.nDataLength < 0 || this->XiPaiData.nDataLength > GAME_DATA_MAX_LENGTH)
                return false;
            break;
        case GAME_DATA_TRANSFER_CHUPAI:
            if(this->ChuPaiData.nDataLength < 0 || this->ChuPaiData.nDataLength > GAME_DATA_MAX_LENGTH)
                return false;
            break;
        case GAME_DATA_TRANSFER_WENTI:
            break;
        case GAME_DATA_TRANSFER_ANSWER:
            break;
        case GAME_DATA_TRANSFER_RANDOM:
            break;
        default:
            return false;
        }
        return true;
    }

};



////////////////////客户/服务端公共数据区///////////////////

//客户端游戏状态
enum _ClientGameStatus
{
    Game_Nothing,   //没加入房间
    Game_Waiting,   //加入了房间,无操作,用户可手动切换到Readying
    Game_Readying,  //加入了房间,准备,用户可手动切换到Waiting
    Game_Playing    //加入了房间,正在玩,用户在一个线程中被操作
};



//////////////////////////////////////////////////////////











/*
//武器坐标

//客户端状态
#define GAME_CLIENT_NORMAL 1
#define GAME_CLIENT_LISTEN 10


//发送数据类型
#define GAME_MSG_LOGIN			100		//登录数据
#define	GAME_MSG_LOGIN_SUCCESS	501		//登录成功
#define	GAME_MSG_LOGIN_FAILED	502		//登录失败
#define GAME_MSG_LOGOUT			200		//注销
#define GAME_MSG_LOGINOFF		201		//登录失败(重复登录)

#define GAME_MSG_NEWONEUP		301		//新人登录
#define GAME_MSG_NEWONEDOWN		302		//新人退出

#define GAME_MSG_REQUESTUPLINELIST	400	//请求在线列表

#define GAME_MSG_TRANSFERDATA	500		//传输数据

//#define GAME_MSG_CONNECTTOPLAY	600		//客户端请求连接
#define GAME_MSG_CONNECTREQUEST	601		//服务端转发客户端请求连接
#define GAME_MSG_CONNECTREQUESTSUCCESS	605		//请求连接成功
#define GAME_MSG_CONNECTREQUESTFAILED	606		//请求连接失败
#define GAME_MSG_CONNECTREPLY	607		//请求连接返回

//服务器信息
#define GAME_SERVER_IP		"127.0.0.1"
#define GAME_SERVER_PORT	9753

//定义常数off-------------------------------------------------
#define TIMER		120		//主时钟周期
#define WIDTH		640		//游戏显示区宽
#define HEIGHT		480		//游戏显示区高
#define GX			40		//地图格宽
#define GY			30		//地图格高


//发送的信息
#define	MSG_UI_REFRESH		100
#define MSG_UI_QUESTIONBOX	101



//手牌的相关坐标
#define POKE_CENTER_X 280	//中间X坐标
#define POKE_CENTER_Y0 200	//中间Y0坐标(顶部)
#define POKE_CENTER_Y1 240	//中间Y1坐标(底部)
#define POKE_TOP_Y 100		//顶部Y坐标


*/


#endif // SOCKETGLOBAL_H


